package cn.zcltd.btg.set.token;

import cn.zcltd.btg.sutil.encrypt.Encryption;
import cn.zcltd.btg.sutil.encrypt.EncryptionKey;

import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;

/**
 * 生成授权码
 */
public class Generater {

    /**
     * 根据配置生成token：
     * 1、过期时间(yyyyMMddHHmmss):ip正则表达式列表:用户名正则表达式列表
     * 例：20170901120959:192\.168\.0\.1,192\.168\.0\.2:user1,user2
     * 2、使用key对上述字符串进行3des加密得到token
     *
     * @param tokenConfig 配置对象
     * @return token
     */
    public static String gen(TokenConfig tokenConfig) {
        try {
            StringBuilder tokenSb = new StringBuilder();

            String timeoutStr = new SimpleDateFormat("yyyyMMddHHmmss").format(tokenConfig.getTimeoutDate());
            tokenSb.append(timeoutStr);

            tokenSb.append(":");

            StringBuilder ipsSb = new StringBuilder();
            for (String ipRegex : tokenConfig.getIpRegex()) {
                ipsSb.append(",").append(ipRegex);
            }
            if (tokenConfig.getIpRegex().size() == 0) {
                ipsSb.append(",").append(".*");
            }
            tokenSb.append(ipsSb.substring(1));

            tokenSb.append(":");

            StringBuilder usersSb = new StringBuilder();
            for (String userRegex : tokenConfig.getUserRegex()) {
                usersSb.append(",").append(userRegex);
            }
            if (tokenConfig.getUserRegex().size() == 0) {
                usersSb.append(",").append(".*");
            }
            tokenSb.append(usersSb.substring(1));

            String ivStr = "12345678";
            byte[] ivBytes = ivStr.getBytes(StandardCharsets.UTF_8);
            EncryptionKey deSedeKey = Encryption.generatorDESedeKey(112, tokenConfig.getKey().getBytes(StandardCharsets.UTF_8));
            return Encryption.encryptDESedeToHex(Encryption.ENCRYPT_MODE_CBC, Encryption.ENCRYPT_PADDING_PKCS5PADDING, tokenSb.toString().getBytes(StandardCharsets.UTF_8), deSedeKey.getKey(), ivBytes);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 将token解析为config
     *
     * @param token 生成的token
     * @param key   key
     * @return config配置对象
     */
    public static TokenConfig token(String token, String key) {
        try {
            /*
                解密token
             */
            String ivStr = "12345678";
            byte[] ivBytes = ivStr.getBytes(StandardCharsets.UTF_8);
            EncryptionKey deSedeKey = Encryption.generatorDESedeKey(112, key.getBytes(StandardCharsets.UTF_8));
            String tokenInfo = Encryption.decryptDESedeFromHexToString(Encryption.ENCRYPT_MODE_CBC, Encryption.ENCRYPT_PADDING_PKCS5PADDING, token, deSedeKey.getKey(), ivBytes);

            /*
                组装config
             */
            TokenConfig tokenConfig = new TokenConfig();
            String[] infos = tokenInfo.split(":");
            String dateStr = infos[0];
            String ipRegexsStr = infos[1];
            String userRegexsStr = infos[2];

            //timeoutDate
            tokenConfig.setTimeoutDate(new SimpleDateFormat("yyyyMMddHHmmss").parse(dateStr));

            //ip
            String[] ipRegexs = ipRegexsStr.split(",");
            for (String ipRegex : ipRegexs) {
                tokenConfig.getIpRegex().add(ipRegex);
            }

            //user
            String[] userRegexs = userRegexsStr.split(",");
            for (String userRegex : userRegexs) {
                tokenConfig.getUserRegex().add(userRegex);
            }

            //key
            tokenConfig.setKey(key);

            return tokenConfig;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}